package org.remixlab.gnutopic.pojo;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;

import org.apache.commons.lang3.StringEscapeUtils;
import org.remixlab.gnutopic.client.SpiralVisualization;
import org.remixlab.gnutopic.client.ThreadIFrame;

import processing.core.PApplet;
import processing.core.PFont;
import processing.core.PVector;

import remixlab.proscene.Scene;

/**
 * Representa un h�lo del foro
 * @author avelandia
 *
 */

public class ForumThread {
	private String id;		//identificador del thread
	private String topic;	//Titulo del hilo 
	private Date date;		//fecha en que se publico el thread.
	
	private ForumCategory category;	//categoria a la que pertenece el hilo.
	
	private String user;	//nombre del usuario que publicó el mensaje
	
	private ArrayList<ForumMessage> messages = new ArrayList<ForumMessage>();
	
	private int replyNumber;	//numero de mensajes dados por otros usuarios.
	
	private boolean visibled = true;	//indica si se debe dibujar el hilo o no.
	
	//datos del cilindro....
	private float x;
	private float y;
	private float z;
	
	private float w;
	private float h;
	
	private SpiralVisualization papplet;
	
	private ThreadIFrame iFrame;
	
	private Scene scene;
	
	private String info = "";
	
	public boolean isVisibled() {
		return visibled;
	}

	public void setVisibled(boolean visibled) {
		//si es igual a all, debo dejar todos los hilos visibles...
		
		if(visibled){
			addIframeFromScene();	
		}else{
			removeIframeFromScene();
		}	
		
		this.visibled = visibled;
	}
	
	public void init (float x, float y, float z, float w, float h){
		this.x = x;
		this.y = y;
		this.z = z;
		
		this.w = w;
		this.h = h;
		
		//inicializo el iFrame
		if(papplet!=null){
			if(scene==null){
				scene = papplet.getScene();	
			}
			
			final PVector vector = new PVector(x,y,z);
			
			if(iFrame==null){
				//creo el interactive frame...
				iFrame = new ThreadIFrame(scene, w, h);	
				
				//le asigno el parent.
				iFrame.setParent(this);
			}
			
			iFrame.setPosition(vector);
		}
		
		info = "Title: "+ this.getTopic();
		
		if(papplet!=null){
			//PFont myFont = papplet.createFont("FFScala", 24);
			//inicializo la fuente...
			//papplet.textFont(myFont);
			//papplet.textMode(PApplet.SCREEN);
			//papplet.textAlign(PApplet.CENTER);
			
		}
	}
	
	public void removeIframeFromScene(){
		scene.removeFromMouseGrabberPool(iFrame);
	}
	
	public void addIframeFromScene(){
		if(!scene.isInMouseGrabberPool(iFrame)){
			scene.addInMouseGrabberPool(iFrame);	
		}
	}

	public int getMessagesNumber(){
		int result = 0;
		if(messages!=null){
			result = messages.size();
		}
		return result;
	}
	
	public String getUser() {
		return user;
	}
	public void setUser(String user) {
		this.user = user;
	}
	public ArrayList<ForumMessage> getMessages() {
		return messages;
	}
	public void setMessages(ArrayList<ForumMessage> messages) {
		this.messages = messages;
	}
	public void addMessage(ForumMessage message){
		if(this.messages!=null){
			this.messages.add(message);	
		}
	}
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getTopic() {
		return topic;
	}
	public void setTopic(String topic) {
		this.topic = topic;
	}
	public Date getDate() {
		return date;
	}
	public void setDate(Date date) {
		this.date = date;
	}
	
	public int getReplyNumber() {
		return replyNumber;
	}
	
	public void setReplyNumber(int replyNumber) {
		this.replyNumber = replyNumber;
	}
	
	public ForumCategory getCategory() {
		return category;
	}
	
	public void setCategory(ForumCategory category) {
		this.category = category;
	}
	
	public float getX() {
		return x;
	}

	public void setX(float x) {
		this.x = x;
	}

	public float getY() {
		return y;
	}

	public void setY(float y) {
		this.y = y;
	}

	public float getZ() {
		return z;
	}

	public void setZ(float z) {
		this.z = z;
	}

	public float getW() {
		return w;
	}

	public void setW(float w) {
		this.w = w;
	}

	public float getH() {
		return h;
	}

	public void setH(float h) {
		this.h = h;
	}

	public SpiralVisualization getPapplet() {
		return papplet;
	}

	public void setPapplet(SpiralVisualization papplet) {
		this.papplet = papplet;
	}

	public ThreadIFrame getiFrame() {
		return iFrame;
	}

	public void setiFrame(ThreadIFrame iFrame) {
		this.iFrame = iFrame;
	}

	public Scene getScene() {
		return scene;
	}

	public void setScene(Scene scene) {
		this.scene = scene;
	}

	public String getInfo() {
		return info;
	}

	public void setInfo(String info) {
		this.info = info;
	}

	public void displayText(){
		papplet.saveState();
		
		//aqui escribo el texto..
		int myWidth = (int) papplet.textWidth(info);
		int myHeight = (int) (papplet.textAscent()+papplet.textDescent());
		
		papplet.fill(papplet.getFontColor());
		papplet.text(info, 0, 0, myWidth, myHeight);
		
		papplet.restoreState();
		
	}
	
	public String toDocXML(){
		String result = "";
		
		StringBuffer buffer = new StringBuffer();
		
		for( ForumMessage message : messages){
			buffer.append(message.toDocXML());
		}
		
		result = buffer.toString();
		
		return result;
	}
	
	public String toString(){
		String result = "";
		
		StringBuffer buffer = new StringBuffer();
		buffer.append("[");
		
		buffer.append("id:");
		buffer.append(id);
		
		buffer.append("\t topic:");
		buffer.append(topic);
		
		buffer.append("\t user:");
		buffer.append(user);
		
		buffer.append("\t date:");
		buffer.append(date);
		
		buffer.append("\t categoryName:");
		buffer.append(category.getName());
		
		buffer.append("]");
		
		result = buffer.toString();
		
		return result;
	}
	
	public void draw(boolean drawAxis){
		if(iFrame.grabsMouse()){
			
			//aqui se dibuja el cilindro y se muestra el título del thread
			papplet.pushMatrix();
			papplet.pushStyle();
		    // Multiply matrix to get in the frame coordinate system.
		    // scene.parent.applyMatrix(iFrame.matrix()) is handy but inefficient
		    iFrame.applyTransformation(); //optimum
		    if(drawAxis) scene.drawAxis(h*1.3f);
		    papplet.noStroke();
		    
		    papplet.fill(255, 0, 0);
		    
		  //Draw a box
		    scene.cylinder(w,h);
		    papplet.popStyle();
		    papplet.popMatrix();
		    
		    displayText();
		    
		    //si se seleccionó el hilo con doble click entonces...
		    if(iFrame.isSelected()){
		    	
		    	if(papplet.getSelectedThread()!=this){
		    		//le digo al applet que el hilo que se selecciono es este hilo..
				    papplet.setSelectedThread(this);
				    
				  //luego le digo al applet que hay un hilo seleccionado..
				    papplet.setSelected(true);
				    
				    //ya llene la variable en el papplet, entonces seteo la variable nuevamente a falso...
				    iFrame.setSelected(false);
		    	}
		    	
		    }
		}
	}

	public String toXml() {
		String result = "";
		
		StringBuffer buffer = new StringBuffer();
		
		DateFormat formatter = new SimpleDateFormat("MM-dd-yy 'at' HH:mm:ss");
		
		buffer.append("\t\t\t<thread>\n");
		
		buffer.append("\t\t\t\t<threadId>");
		buffer.append(this.id);
		buffer.append("</threadId>\n");
		
		buffer.append("\t\t\t\t<threadTitle>");
		buffer.append(StringEscapeUtils.escapeXml(this.topic));
		buffer.append("</threadTitle>\n");
		
		buffer.append("\t\t\t\t<threadUser>");
		buffer.append(StringEscapeUtils.escapeXml(this.user));
		buffer.append("</threadUser>\n");
		
		buffer.append("\t\t\t\t<threadDate>");
		buffer.append(formatter.format(this.date));
		buffer.append("</threadDate>\n");
		
		buffer.append("\t\t\t\t<messages>\n");
		for( ForumMessage message : messages){
			buffer.append(message.toXML());
		}
		buffer.append("\t\t\t\t</messages>\n");
		
		buffer.append("\t\t\t</thread>\n");
		
		result = buffer.toString();
		
		return result;
	}
	
}
